// Main entry point

#include <multiboot.h>
#include <debug.h>
#include <pmm.h>
#include <mmap.h>

size_t g_lowmem;
size_t g_highmem;

/**
 * Check Magic value passed into entry point from bootloader
 * 
 * magic - magic number to check
 */
int check_multiboot_magic(dword magic)
{
	if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
		return MB_ERR_BADMAGIC;
	
	return 0;
}

/**
 * Print info contained in the multiboot header
 * 
 * ! Initializes pmm and mmap systems
 * 
 * multiboot_info_t *mbi - ptr to multiboot header
 */
void init_multiboot_info(multiboot_info_t *mbi)
{	
	if (CHECK_FLAG(mbi->flags, 0)) {
		debugf("Upper Memory: %uKB\n", mbi->mem_upper);
		debugf("Lower Memory: %uKB\n", mbi->mem_lower);
		
		g_lowmem = mbi->mem_lower;
		g_highmem = mbi->mem_upper;
	}
	
	if (CHECK_FLAG(mbi->flags, 3)) {
		int i;
		module_t *mod;
		
		for (i = 0, mod = (module_t*)mbi->mods_addr;
		 i < mbi->mods_count; i++, mod++)
		{
			debugf("Module: %s\n", mod->string);
		}
	}
	
	if (CHECK_FLAG(mbi->flags, 6)) {
		memory_map_t *mmap;
		dword /*ext_addr_high,*/ ext_addr_low;
		
		for (mmap = (memory_map_t*)mbi->mmap_addr;
		 (dword)mmap < mbi->mmap_addr + mbi->mmap_length;
		 mmap = (memory_map_t*)((dword)mmap + mmap->size + sizeof(mmap->size)))
		{
			/*
			 * be 64-bit
			ext_addr_high = mmap->base_addr_high + mmap->length_high;
			ext_addr_low = mmap->base_addr_low + mmap->length_low;
			if (ext_addr_low < mmap->base_addr_low)
				ext_addr_high++;
			
			debugf("0x%08x %08x - 0x%08x %08x (0x%x)\n",
			 mmap->base_addr_high, mmap->base_addr_low,
			 ext_addr_high, ext_addr_low, mmap->type);
			 */
			
			// be 32-bit for now
			ext_addr_low = mmap->base_addr_low + mmap->length_low;
			if (ext_addr_low < mmap->base_addr_low)
				ext_addr_low = 0xFFFFFFFF;
			debugf("0x%08x - 0x%08x (%d)\n", mmap->base_addr_low, ext_addr_low, mmap->type);
		}
	}
}

/**
 * Return the address of the Exended BIOS Data Area
 */
dword get_ebda_addr(void)
{
	word *m = (word*)EBDA_PTR;
	
	return (dword)*m;
}
